package org.jeecg.modules.zcgl.controller;

import com.alibaba.fastjson.JSON;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.core.metadata.IPage;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import io.swagger.annotations.Api;
import io.swagger.annotations.ApiOperation;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.lang3.StringUtils;
import org.jeecg.common.api.vo.Result;
import org.jeecg.common.aspect.annotation.AutoLog;
import org.jeecg.common.constant.CommonConstant;
import org.jeecg.common.system.api.ISysBaseAPI;
import org.jeecg.common.system.base.controller.JeecgBaseController;
import org.jeecg.common.system.query.QueryGenerator;
import org.jeecg.common.system.util.JwtUtil;
import org.jeecg.common.system.vo.DictModel;
import org.jeecg.common.system.vo.LoginUser;
import org.jeecg.common.util.BigDecimalUtils;
import org.jeecg.common.util.ReflectHelper;
import org.jeecg.modules.activiti.enums.ResultEnum;
import org.jeecg.modules.system.entity.SysUser;
import org.jeecg.modules.system.service.ISysConfigService;
import org.jeecg.modules.system.service.ISysUserService;
import org.jeecg.modules.system.service.impl.SysBaseApiImpl;
import org.jeecg.modules.zcgl.entity.*;
import org.jeecg.modules.zcgl.service.*;
import org.jeecg.modules.zcgl.tencent.service.IWxSendMessageService;
import org.jeecg.modules.zcgl.vo.ContractPrintVo;
import org.jeecg.modules.zcgl.vo.ReceivablesInfoVo;
import org.jeecg.modules.zcgl.vo.ReceivablesPrintVo;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.*;
import org.springframework.web.servlet.ModelAndView;

import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.math.BigDecimal;
import java.text.DecimalFormat;
import java.text.SimpleDateFormat;
import java.util.*;

/**
 * @Description: 应收款项信息
 * @Author: jeecg-boot
 * @Date: 2020-06-23
 * @Version: V1.0
 */
@Api(tags = "应收款项信息")
@RestController
@RequestMapping("/zcgl/receivablesInfo")
@Slf4j
public class ReceivablesInfoController extends JeecgBaseController<ReceivablesInfo, ReceivablesInfo, IReceivablesInfoService> {

    @Autowired
    private IReceivablesInfoService receivablesInfoService;
    @Autowired
    private ILeaseContractInfoService leaseContractInfoService;
    @Autowired
    private ICustomerInfoService customerInfoService;
    @Autowired
    private IWxSendMessageService sendMessageService;
    @Autowired
    private ISysConfigService sysConfigService;
    @Autowired
    private SysBaseApiImpl baseApi;
    @Autowired
    private IAssetInfoService assetInfoService;
    @Autowired
    private ISysBaseAPI iSysBaseAPI;
    @Autowired
    private ISysUserService iSysUserService;


    /**
     * 分页列表查询
     *
     * @param receivablesInfo
     * @param pageNo
     * @param pageSize
     * @param req
     * @return
     */
    @AutoLog(value = "应收款项信息-分页列表查询")
    @ApiOperation(value = "应收款项信息-分页列表查询", notes = "应收款项信息-分页列表查询")
    @GetMapping(value = "/list")
    public Result<?> queryPageList(ReceivablesInfo receivablesInfo,
                                   @RequestParam(name = "pageNo", defaultValue = "1") Integer pageNo,
                                   @RequestParam(name = "pageSize", defaultValue = "10") Integer pageSize,
                                   HttpServletRequest req) {

        Map<String, String[]> parameterMap = new HashMap(req.getParameterMap());
        parameterMap.remove("managerId");
        parameterMap.remove("regional");
        QueryWrapper<ReceivablesInfo> queryWrapper = QueryGenerator.initQueryWrapper(receivablesInfo, req.getParameterMap());

        if (StringUtils.isNotBlank(req.getParameter("managerId"))) {
            queryWrapper.lambda().inSql(ReceivablesInfo::getAssetId, "SELECT asset.id FROM zcgl_asset_info AS asset WHERE asset.manager_id = '" + req.getParameter("managerId") + "'");
        }
        if(StringUtils.isNotBlank(req.getParameter("regional"))){
            queryWrapper.lambda().inSql(ReceivablesInfo::getAssetId, "SELECT asset.id FROM zcgl_asset_info AS asset WHERE asset.regional = '" + req.getParameter("regional") + "'");
        }

        queryWrapper.lambda().orderByAsc(ReceivablesInfo::getPayStatus);
        queryWrapper.lambda().orderByAsc(ReceivablesInfo::getPayStartDate);
        Page<ReceivablesInfo> page = new Page<ReceivablesInfo>(pageNo, pageSize);
        IPage<ReceivablesInfo> pageList = receivablesInfoService.page(page, queryWrapper);

        return Result.ok(pageList);
    }

    /**
     * 通过id查询
     *
     * @param id
     * @return
     */
    @AutoLog(value = "应收账单打印信息-通过id查询")
    @ApiOperation(value = "应收账单打印信息-通过id查询", notes = "应收账单打印信息-通过id查询")
    @GetMapping(value = "/queryPrintById")
    public Result<?> queryPrintById(@RequestParam(name = "id", required = true) String id,
                                    @RequestParam(name = "printTemplateId", required = true) String printTemplateId,
                                    @RequestParam(name = "payeeAmount", required = true) String payeeAmount) {
        ReceivablesInfo receivablesInfo = receivablesInfoService.getById(id);
        if (receivablesInfo == null) {
            return Result.error("未找到对应数据");
        }
        if(printTemplateId==null){
            return Result.error("未找到模板");
        }
        DecimalFormat df = new DecimalFormat("###,##0.00");
        SimpleDateFormat sdf=new SimpleDateFormat("yyy-MM-dd");
        ReceivablesPrintVo vo = new ReceivablesPrintVo();

        AssetInfo assetInfo= assetInfoService.getById(receivablesInfo.getAssetId());
        //获取所有管区
        Map<String,String> regionalMap=new HashMap<String,String>();
        List<DictModel> dictModels=iSysBaseAPI.queryDictItemsByCode("zcgl_regional");
        for (DictModel dict: dictModels) {
            regionalMap.put(dict.getValue(),dict.getText());
        }
        int regional=assetInfo.getRegional()==null?0:assetInfo.getRegional();
        //管区
        vo.setRegional(regionalMap.get(regional));
        //房屋地址
        vo.setHomeAddr(assetInfo.getSite());
        //付款人
        CustomerInfo customerInfo= customerInfoService.getById(receivablesInfo.getPaymentBy());
        vo.setPayer(customerInfo.getName());
        //月租金
        LeaseContractInfo leaseContractInfo= leaseContractInfoService.getById(receivablesInfo.getLeaseContractId());
        vo.setMonthlyRent(BigDecimalUtils.formatToThousands(leaseContractInfo.getMonthlyRent()));
        //付款金额
        vo.setPayAmount(BigDecimalUtils.formatToThousands(new BigDecimal(payeeAmount)));
        //缴费时间
        vo.setPayDate(sdf.format(receivablesInfo.getReceiptDate()));
        //判断是否选择收款人，默认当前登录用户
        String drawerName="";
        if (StringUtils.isBlank(receivablesInfo.getPayeeBy())) {
            LoginUser sysUser = JwtUtil.getLoginUser();
            drawerName=sysUser.getUsername();
        }else{
            SysUser SysUser= iSysUserService.getById(receivablesInfo.getPayeeBy());
            drawerName=SysUser.getUsername();
        }
        //开票人
        vo.setDrawer(drawerName);
        //时间
        vo.setDate(sdf.format(receivablesInfo.getReceiptDate()));

        Map<String, Object> newMap = ReflectHelper.objectToMap(vo);
        String content = baseApi.parseTemplateById(printTemplateId, newMap);

        return Result.ok(content,"");
    }

    /**
     * 添加
     *
     * @param receivablesInfo
     * @return
     */
    @AutoLog(value = "应收款项信息-添加")
    @ApiOperation(value = "应收款项信息-添加", notes = "应收款项信息-添加")
    @PostMapping(value = "/add")
    public Result<?> add(@RequestBody ReceivablesInfo receivablesInfo) {
        service.checkModel(receivablesInfo);
        receivablesInfoService.saveOrUpdateById(receivablesInfo);
        return Result.ok("添加成功！");
    }

    /**
     * 编辑
     *
     * @param receivablesInfo
     * @return
     */
    @AutoLog(value = "应收款项信息-编辑")
    @ApiOperation(value = "应收款项信息-编辑", notes = "应收款项信息-编辑")
    @PutMapping(value = "/edit")
    public Result<?> edit(@RequestBody ReceivablesInfo receivablesInfo) {
        service.checkModel(receivablesInfo);
        receivablesInfoService.saveOrUpdateById(receivablesInfo);
        return Result.ok("编辑成功!");
    }
    /**
     * 检测是否合法
     *
     * @param receivablesInfo
     * @return
     */
    @AutoLog(value = "应收款项信息-检测是否合法")
    @ApiOperation(value = "应收款项信息-检测是否合法", notes = "应收款项信息-检测是否合法")
    @PostMapping(value = "/checkModel")
    public Result<?> checkModel(@RequestBody ReceivablesInfo receivablesInfo) {
        service.checkModel(receivablesInfo);
        return Result.ok("检测通过！");
    }

    @AutoLog(value = "应收款项信息-收款")
    @ApiOperation(value = "应收款项信息-收款", notes = "应收款项信息-收款")
    @PostMapping(value = "/toll")
    public Object toll(ReceivablesInfo vo) {
        if (vo.getPayType() == null) {
            return Result.error("请选择支付方式");
        }
        if (vo.getReceiptDate() == null) {
            return Result.error("请选择收费日期");
        }
        if (vo.getPayeeAmount() == null || vo.getPayeeAmount().compareTo(BigDecimal.ZERO) < 0) {
            return Result.error("请输入正确的收款金额");
        }
        if (StringUtils.isBlank(vo.getPaymentBy())) {
            return Result.error("请选择付款人");
        }
        receivablesInfoService.toll(vo);
        return Result.ok("收款成功!");
    }

    @AutoLog(value = "应收款项信息-收款金额确认")
    @ApiOperation(value = "应收款项信息-收款金额确认", notes = "应收款项信息-收款金额确认")
    @PostMapping(value = "/amountConfirmation")
    public Result<String> amountConfirmation(@RequestParam(name = "id", required = true) String id,
                                             @RequestParam(name = "isAllConfirmation", required = true) Integer isAllConfirmation) {
        receivablesInfoService.amountConfirmation(id, isAllConfirmation);

        return Result.ok("确认成功!");
    }

    @AutoLog(value = "应收款项信息-拆费检测")
    @ApiOperation(value = "应收款项信息-拆费检测", notes = "应收款项信息-拆费检测")
    @PostMapping(value = "/demolitionFeeCheckModel")
    public Object demolitionFeeCheckModel(@RequestBody ReceivablesInfoVo vo) {
        receivablesInfoService.demolitionFeeCheckModel(vo);
        return Result.ok("拆费检测成功！");
    }

    @AutoLog(value = "已收款项信息-作废")
    @ApiOperation(value = "已收款项信息-作废", notes = "已收款项信息-作废")
    @PostMapping(value = "/nullify")
    public Object nullify(ReceivablesInfo vo) {
        receivablesInfoService.nullify(vo);
        return Result.ok("作废成功！");
    }

    @AutoLog(value = "应收款项信息-拆费")
    @ApiOperation(value = "应收款项信息-拆费", notes = "应收款项信息-拆费")
    @PutMapping(value = "/demolitionFee")
    public Object demolitionFee(@RequestBody ReceivablesInfoVo vo) {
        ReceivablesInfo receivablesInfo = receivablesInfoService.getById(vo.getId());
        if (receivablesInfo == null) {
            return Result.error("应收款项信息不存在");
        }
        String isApproval = sysConfigService.getValueByKey(CommonConstant.IS_APPROVAL);
        if ("1".equalsIgnoreCase(isApproval)){
            if (receivablesInfo.getProcessStatus() == null || receivablesInfo.getProcessStatus() != ResultEnum.RESULT_PASS.getStatus()) {
                return Result.error("未审批通过不能拆费");
            }
        }
        receivablesInfoService.demolitionFee(vo);
        return Result.ok("拆费成功!");
    }

    /**
     * 通过id删除
     *
     * @param id
     * @return
     */
    @AutoLog(value = "应收款项信息-通过id删除")
    @ApiOperation(value = "应收款项信息-通过id删除", notes = "应收款项信息-通过id删除")
    @DeleteMapping(value = "/delete")
    public Result<?> delete(@RequestParam(name = "id", required = true) String id) {
        receivablesInfoService.removeById(id);
        return Result.ok("删除成功!");
    }

    /**
     * 批量删除
     *
     * @param ids
     * @return
     */
    @AutoLog(value = "应收款项信息-批量删除")
    @ApiOperation(value = "应收款项信息-批量删除", notes = "应收款项信息-批量删除")
    @DeleteMapping(value = "/deleteBatch")
    public Result<?> deleteBatch(@RequestParam(name = "ids", required = true) String ids) {
        this.receivablesInfoService.removeByIds(Arrays.asList(ids.split(CommonConstant.DEFAULT_SEPARATOR)));
        return Result.ok("批量删除成功!");
    }

    /**
     * 通过id查询
     *
     * @param id
     * @return
     */
    @AutoLog(value = "应收款项信息-通过id查询")
    @ApiOperation(value = "应收款项信息-通过id查询", notes = "应收款项信息-通过id查询")
    @GetMapping(value = "/queryById")
    public Result<?> queryById(@RequestParam(name = "id", required = true) String id) {
        ReceivablesInfo receivablesInfo = receivablesInfoService.getById(id);
        if (receivablesInfo == null) {
            return Result.error("未找到对应数据");
        }
        return Result.ok(receivablesInfo);
    }

    /**
     * 通过ids提醒用户缴费
     *
     * @param ids
     * @return
     */
    @AutoLog(value = "应收款项信息-消息提醒用户缴费")
    @ApiOperation(value = "应收款项信息-消息提醒用户缴费", notes = "应收款项信息-消息提醒用户缴费")
    @PostMapping(value = "/paymentReminder")
    public Result<?> paymentReminder(@RequestParam(name = "ids", required = true) String ids) {
        String[] idsStr = ids.split(CommonConstant.DEFAULT_SEPARATOR);
        Map<String, Boolean> reMap = sendMessageService.paymentReminder(idsStr);
        List<Integer> list = new ArrayList<>();
        int i = 1;
        String message = "提醒失败!";
        for (Map.Entry<String, Boolean> entry : reMap.entrySet()) {
            if (!entry.getValue()) {
                list.add(i);
                message = entry.getKey();
            }
            i++;
        }
        if (list.size() == 0) {
            return Result.ok("提醒成功!");
        }
        if (idsStr.length == 1) {
            return Result.error(message);
        }
        return Result.error("第【" + JSON.toJSONString(list) + "】条提醒失败!");
    }

    /**
     * 导出excel
     *
     * @param request
     * @param receivablesInfo
     */
    @RequestMapping(value = "/exportXls")
    public ModelAndView exportXls(HttpServletRequest request, ReceivablesInfo receivablesInfo) {
        return super.exportXls(request, receivablesInfo, ReceivablesInfo.class, "应收款项信息");
    }

    /**
     * 通过excel导入数据
     *
     * @param request
     * @param response
     * @return
     */
    @RequestMapping(value = "/importExcel", method = RequestMethod.POST)
    public Result<?> importExcel(HttpServletRequest request, HttpServletResponse response) {
        return super.importExcel(request, response, ReceivablesInfo.class);
    }

    @Override
    public List<ReceivablesInfo> exportList(List<ReceivablesInfo> list) {
        return list;
    }

    @Override
    public boolean importSave(ReceivablesInfo vo) {
        service.checkModel(vo);
        receivablesInfoService.save(vo);
        return true;
    }

}
